#ifndef QJSHIGHLIGHT_H
#define QJSHIGHLIGHT_H

#include "qjsscanner.h"
#include "js_editor_global.h"
#include "basetextdocumentlayout.h"

#include <QSyntaxHighlighter>

class JSEDITOR_EXPORT QJSHighLight : public QObject
{
    Q_OBJECT
public:
    enum {
        NumberFormat,
        StringFormat,
        TypeFormat,
        KeywordFormat,
        FieldFormat,
        CommentFormat,
        VisualWhitespace,
        NumFormats
    };

    QJSHighLight(QTextDocument *parent);

    QTextDocument *document() const;

    void setExtraAdditionalFormats(const QTextBlock& block, QList<QTextLayout::FormatRange> &formats);


    static QList<QColor> generateColors(int n, const QColor &background);
protected:
    void highlightBlock(const QString &text);

    void setFormat(int start, int count, const QTextCharFormat &format);
    void setFormat(int start, int count, const QColor &color);
    void setFormat(int start, int count, const QFont &font);
    QTextCharFormat format(int pos) const;

    void applyFormatToSpaces(const QString &text, const QTextCharFormat &format);


    int previousBlockState() const;
    int currentBlockState() const;
    void setCurrentBlockState(int newState);


    void setCurrentBlockUserData(QTextBlockUserData *data);
    QTextBlockUserData *currentBlockUserData() const;

    QTextBlock currentBlock() const;

    void onOpeningParenthesis(QChar parenthesis, int pos, bool atStart);
    void onClosingParenthesis(QChar parenthesis, int pos, bool atEnd);
    void onBlockEnd(int state);
    int  onBlockStart();

    void reformatBlocks(int from, int charsRemoved, int charsAdded);
    void reformatBlock(const QTextBlock &block, int from, int charsRemoved, int charsAdded);
    void applyFormatChanges(int from, int charsRemoved, int charsAdded);
    void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation);
signals:
public slots:
    void rehighlight();
    void rehighlightBlock(const QTextBlock &block);
protected slots:
    void reformatBlocks_slot(int from, int charsRemoved, int charsAdded);
    void delayedRehighlight();
protected:
    QVector<QTextCharFormat> m_formatChanges;
    QTextDocument   *m_doc;
    bool        m_rehighlightPending;
    bool        m_inReformatBlocks;
    BaseTextDocumentLayout::FoldValidator m_foldValidator;
    QTextBlock m_currentBlock;


    QTextCharFormat m_formats[NumFormats];
    Scanner     m_scanner;
    bool m_inMultilineComment;
    int m_braceDepth;
    int m_foldingIndent;
    Parentheses m_currentBlockParentheses;
};

#endif // QJSHIGHLIGHT_H
